<?php /** @noinspection ALL */

/**
 * @author spenceryg
 * @date 2023/3/28
 * @time 7:06 上午
 * @focus love & life
 */

namespace app\api\controller;

use app\BaseController;
use app\common\lib\ChatGpt;
use app\common\lib\verify\AliSmsVerify;
use app\common\lib\verify\VerifyFactory;
use app\common\model\ApikeyLibrary;
use app\common\model\MemberFile;
use app\common\model\PushLog;
use app\common\model\PushPlan;
use hg\apidoc\annotation as Apidoc;
use app\common\model\ArticleContent;
use app\common\model\GptRequestLog;
use app\common\model\GptStrategy;
use app\common\model\GptToken;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Response;
use think\facade\Db;

/**
 * Class Cron
 * @package app\api\controller
 *
 * @Apidoc\Title("定时任务")
 * @Apidoc\Group("api")
 */
class Cron extends BaseController
{
    /**
     * @Apidoc\Title("按照用户生成")
     * 按照用户生成
     * createPerMember
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function createArticlesPerMember(): string
    {
        $articles = \app\common\model\Article::where('state', 0)
            ->where('is_creating', '<',time()-600)
            ->group('member_id')
            ->limit(2)->select();
        //dump($articles);exit;
        if (!$articles->isEmpty()) {
            $this->doCreate($articles);
        }
        return 'success';

    }


    /**
     * @Apidoc\Title("按照最先提交生成")
     * 按照最先提交生成
     * createOld
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function createArticlesOld(): string
    {
        $articles = \app\common\model\Article::where('state', 0)
            ->where('is_creating', '<',time()-600)
            ->order('article_title_task_id asc,create_time asc')
            ->limit(2)->select();

        if (!$articles->isEmpty()) {
            $this->doCreate($articles);
        }
        return 'success';
    }

    /**
     * @Apidoc\Title("更新临时下架的key")
     * renewApiKey
     */
    public function renewApiKey(): string
    {
        $key = ApikeyLibrary::where('state', 2)->where('end_time','<', time() - 60*10)->order('update_time' ,'asc')->find();
        $key->force(true)->save();
        if($key){
            $client = new Client([
//            'base_uri' => 'https://api.openai.com/v1/chat/completions',
                'base_uri' => config('transfer.transit_address'),
                'timeout' => 200,
                'verify' => false,
            ]);
            try{
                $res = $client->post('',
                    [
                        'verify' => false,
                        'headers' => [
                            'Authorization' => "Bearer " . $key['name'],
                        ],
                        'json' => [
                            'model' => 'gpt-3.5-turbo',
                            'messages' => [
                                [
                                    "role" => "user",
                                    "content" => '你好'
                                ],
                            ],
                        ]
                    ]
                );
                if($res->getBody()->getContents()){
                    $key->state = 0;
                    $key->end_time = 0;
                    $key->usage_time = 0;
                    $key->end_reason = '';
                    $key->save();
                }
                return 'success';


            }catch (\Exception $e){
                dump($e);
                dump($key->id);
                return 'end';
            }
        }
        return 'no find';
    }


    /**
     * doCreate
     * @param $articles
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function doCreate($articles): void
    {

        foreach ($articles as $article) {
            \app\common\model\Article::update([
                'id' => $article['id'],
                'is_creating' => time()
            ]);
        }
        $url = 'https://open.bigmodel.cn/api/paas/v3/model-api/chatglm_std/invoke';
        $client = new Client([
//            'base_uri' => 'https://api.openai.com/v1/chat/completions',
            'base_uri' => $url,
            'timeout' => 300,
            'verify' => false,
        ]);

        $strategy = GptStrategy::order('update_time', 'asc')->find();
        $strategy_name = $strategy['name'];
        $strategy->force()->save();

//        $tokenModel = GptToken::order('update_time', 'asc')->where('id', '>', 1)->find();
//        $token_key = $tokenModel['token'];
//        $tokenModel->force()->save();

        $count = count($articles);
        $api_key_arr = [];
        $api_key_ids = [];
        for($i=0;$i<$count;$i++){
            $tokenModel = GptToken::where("category","智谱AI")->order('update_time', 'asc')->find();
            $token_key = $tokenModel['token'];
            $tokenModel->force()->save();
            $api_key_arr[] = $token_key;
            $api_key_ids[] = $tokenModel['id'];
        }


        $requests_fun = function ($articles) use ($token_key, $client, $strategy_name, $api_key_arr) {
            foreach ($articles as $i => $article) {
                $msg = str_replace('{title}', $article['name'], $strategy_name);
                $msg = str_replace('{length}', $article['length'], $msg);
                if($article['lang']){
                    $msg.=" 生成语言为```{$article['lang']}```";
                }
                $msg.="。并且在文章最后一行给出关键词";
                $this_api_key = $api_key_arr[$i];
                yield function () use ($client, $msg, $token_key, $this_api_key) {
                    return $client->postAsync('',
                        [
                            'verify' => false,
                            'headers' => [
                                'Authorization' => ChatGpt::generate_token($this_api_key,80),
                            ],
                            'json' => [
//                                'model' => 'gpt-3.5-turbo',
                                'prompt' => [
                                    [
                                        "role" => "user",
                                        "content" => $msg
                                    ],
                                ],
//                                'query' => $msg,
//                                'sse' => false
                                //'max_tokens' => 3600,//这里不要限制token否则当输入的token比较多的时候会报错
                            ]
                        ]
                    );
                };

            }
        };
        $articles_arr = [];
        if (!$articles->isEmpty()) {
            $articles_arr = $articles->toArray();
        }
        $pool = new Pool($client, $requests_fun($articles), [
            'concurrency' => 60,
            'fulfilled' => function (Response $response, $index) use ($articles_arr, $strategy_name, $api_key_ids) {
                $res = $response->getBody()->getContents();
                $res = json_decode($res, true);
                $res = $res['data'];
                $getcontent = $res['choices'][0]['content'];
                $getcontent=str_replace("\\n","\r\n",$getcontent);//将智谱ai接口返回的\n\n替换为\r\n

                //todo extractKeywords函数调整
                list($content, $keywords) = $this->extractKeywords($getcontent);

                //$content = $getcontent;
                //如果生成的内容小于100字，重新生成
                if(mb_strlen($content)<100){
                    $id = $articles_arr[$index]['id'];
                    \app\common\model\Article::update([
                        'id' => $id,
                        'is_creating' => 0
                    ]);

                    $article = $articles_arr[$index];
                    $msg = str_replace('{title}', $article['name'], $strategy_name);
                    $gtpLog = [];
                    $gtpLog['name'] = $msg;
                    $gtpLog['prompt_tokens'] = -1;
                    $gtpLog['total_tokens'] = -1;
                    $gtpLog['completion_tokens'] = -1;
                    $gtpLog['member_id'] = $article['member_id'];
                    $gtpLog['gpt_token_id'] = $api_key_ids[$index];
                    $gtpLog['article_id'] = $article['id'];
                    $gtpLog['reason_for_error'] = "生成文章字数少于100";
                    GptRequestLog::create($gtpLog);
                }else{
                    $article = $articles_arr[$index];
                    $msg = str_replace('{title}', $article['name'], $strategy_name);
                    if($article['lang']){
                        $msg.=" 生成语言为```{$article['lang']}```";
                    }
                    $gtpLog = [];
                    $gtpLog['name'] = $msg;
                    $gtpLog['prompt_tokens'] = $res['usage']['prompt_tokens'];
                    $gtpLog['total_tokens'] = $res['usage']['total_tokens'];
                    $gtpLog['completion_tokens'] = $res['usage']['completion_tokens'];
                    $gtpLog['member_id'] = $article['member_id'];
                    $gtpLog['gpt_token_id'] = $api_key_ids[$index];
                    $gtpLog['article_id'] = $article['id'];
                    $gtpLog['reason_for_error'] = '';
                    GptRequestLog::create($gtpLog);


                    $id = $article['id'];
                    $state = 2;
                    if ($article['type'] == 1) {
                        $state = 1;
                    }
                    \app\common\model\Article::update([
                        'id' => $id,
                        'keywords'=>$keywords,
                        'state' => $state
                    ]);
                    //                $content = str_replace(['<article>','</article>'], ['',''], $content);
                    $content = $this->createHtml($content, $article['name']);

                    // 违禁词替换
                    if($article['forbiddenwords_id']){
                        $forbiddenwords = \app\common\model\ArticleForbiddenwords::find($article['forbiddenwords_id']);
                        $words = trim($forbiddenwords['content']);
                        $arr = explode("\n", $words);
                        $replace_arr = [];
                        foreach ($arr as $replace){
                            $this_replace = explode('=', $replace, 2);
                            $key = $this_replace[0];
                            $val = isset($this_replace[1])?$this_replace[1]:'';
                            if(!$val){
                                $len = mb_strlen($key);
                                $val = str_repeat('*', $len);
                            }
                            $replace_arr[$key] = $val;
                        }
                        foreach ($replace_arr as $key => $val) {
                            $content = str_replace($key, $val, $content);
                        }
                    }
                    ArticleContent::where('article_id', $id)->save(['name' => $content, 'update_time'=>time()]);
                }
            },
            'rejected' => function (RequestException $reason, $index) use ($articles_arr, $strategy_name, $api_key_ids, $api_key_arr) {

                $id = $articles_arr[$index]['id'];
                \app\common\model\Article::update([
                    'id' => $id,
                    'is_creating' => 0
                ]);


                $article = $articles_arr[$index];
                $msg = str_replace('{title}', $article['name'], $strategy_name);
                $msg = str_replace('{length}', $article['length'], $strategy_name);
                $gtpLog = [];
                $gtpLog['name'] = $msg;
                $gtpLog['prompt_tokens'] = -1;
                $gtpLog['total_tokens'] = -1;
                $gtpLog['completion_tokens'] = -1;
                $gtpLog['member_id'] = $article['member_id'];
                $gtpLog['gpt_token_id'] = $api_key_ids[$index];
                $gtpLog['article_id'] = $article['id'];
                $gtpLog['reason_for_error'] = $reason->getResponse()->getReasonPhrase();

                GptRequestLog::create($gtpLog);


                $token = $api_key_arr[$index];
                $apiKey = ApikeyLibrary::where('state', 0)->order('id', 'asc')->find();
                if($apiKey){
                    $gptToken = GptToken::where('token', $token)->find();
                    if($gptToken){
                        $gptToken->token = $apiKey->name;
                        $gptToken->save();

                        $apiKey->state = 1;
                        $apiKey->usage_time = date('Y-m-d H:i:s', time());
                        $apiKey->save();

                        $oldApiKey = ApikeyLibrary::where('name', $token)->find();
                        $oldApiKey->end_time = date('Y-m-d H:i:s', time());
                        if($msg == 'Unauthorized'){
                            $oldApiKey->state = 3;
                        }else{
                            $oldApiKey->state = 2;
                        }
                        $oldApiKey->end_reason = $msg;
                        $oldApiKey->save();
                    }
//                    $gptToken->token = $apiKey->name;
//                    $gptToken->save();
//                GptToken::where('token', $token)->save(['token'=>$apiKey->name]);

                }else{
//                    $factory = new VerifyFactory(new AliSmsVerify());
//                    $factory->setTo('15821183928')->setCode('88888888')->send();
                }
            },
        ]);

        $promise = $pool->promise();
        $promise->wait();
    }


    /**
     * doPlan
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @Apidoc\Title("执行任务")
     */
    public function doPlan()
    {
        exit;//已经通过task模块发送了，这里不用了
        $plan_id = input('id');
        $plan = PushPlan::find($plan_id);
        $ids = [];
        if($plan['number_of_articles']){
            $ids = \app\common\model\Article::where('member_id', $plan['member_id'])
                ->where('article_class_id', $plan['article_class_id'])
                ->where('state', 2)
                ->limit($plan['number_of_articles'])
                ->column('id');
        }
        $items = [];
        if ($ids) {
            foreach ($ids as $index => $id) {
                $items[$index] = $this->getPushFormData($id, $plan['site_id'],
                    $plan['site_cat_id'],
                    $plan['is_insert_picture'],
                    $plan['img_class_id'],
                    $plan_id);
            }
        }
        $client = new Client([
            'timeout' => 800,
            'verify' => false,
        ]);
        $requests_fun = function ($articles) use ($client) {
            foreach ($articles as $article) {
                yield function () use ($client, $article) {
                    return $client->postAsync($article['url'],
                        [
                            'verify' => false,
                            'form_params' => $article['form'],
                            'headers' => $article['headers']
                        ]
                    );
                };
            }
        };
        $pool = new Pool($client, $requests_fun($items), [
            'concurrency' => 5,
            'fulfilled' => function (Response $response, $index) use ($items) {
                $res = $response->getBody()->getContents();
                if (strpos($res, $items[$index]['flag']) !== false) {
                    \app\common\model\Article::where('id', $items[$index]['article_id'])->save([
                        'state' => 3,
                        'push_time' => time(),
                        'site_id' => $items[$index]['site_id']
                    ]);
                    PushLog::create([
                        'state' => 1,
                        'member_id' => $items[$index]['member_id'],
                        'article_id' => $items[$index]['article_id'],
                        'push_plan_id' => $items[$index]['id'],
                        'site_id' => $items[$index]['site_id'],
                        'site_catid' => $items[$index]['site_catid'],
                    ]);
                    \app\common\model\Site::update([
                        'id' => $items[$index]['site_id'],
                        'today_quantity' => Db::raw('today_quantity+1'),
                        'cumulative_quantity' => Db::raw('cumulative_quantity+1'),
                    ]);

                } else {
                    PushLog::create([
                        'state' => 0,
                        'member_id' => $items[$index]['member_id'],
                        'article_id' => $items[$index]['article_id'],
                        'push_plan_id' => $items[$index]['id'],
                        'site_id' => $items[$index]['site_id'],
                        'site_catid' => $items[$index]['site_catid'],
                        'remarks' => '返回值无成功标志。'. $res
                    ]);
                }

            },
            'rejected' => function (RequestException $reason, $index) use ($items) {
                PushLog::create([
                    'state' => 0,
                    'member_id' => $items[$index]['member_id'],
                    'article_id' => $items[$index]['article_id'],
                    'push_plan_id' => $items[$index]['id'],
                    'site_id' => $items[$index]['site_id'],
                    'site_catid' => $items[$index]['site_catid'],
                    'remarks' => '网络请求错误。'. $reason->getMessage()
                ]);
            },
        ]);
        $promise = $pool->promise();
        $promise->wait();
        return 'success';
    }


    private function getPushFormData($id, $site_id, $site_class_id, $is_insert_img, $img_class_id, $plan_id)
    {
        $article = \app\common\model\Article::find($id);
        $site = \app\common\model\Site::find($site_id);
        $siteLink = \app\common\model\SiteLink::where("site_id","=",$site_id)->select();

        $form_data = [];
        $form_data[$site['column_field']] = $site_class_id;
        $form_data[$site['article_content_field']] = $article->articleContent->name;
        $form_data[$site['create_time_field']] = date('y-m-d H:i:s', time());
        $form_data[$site['title_field']] = $article->name;
        $form_data['key'] = $site['secret_key'];
        $url = $site['website'] . $site['publishing_interface'];
        $split_flag = '?';
        if(strpos($url,'?')!==false){
            $split_flag = '&';
        }
        $url = ($site['is_https'] ? 'https://' : 'http://') . $url .$split_flag  .'key=' . $site['secret_key'];
        //锚链接替换
        if($siteLink){
            foreach ($siteLink as $link) {
                $patten = '/(?<!href=")(?<!alt=")' .$link['name']. '(?!<\/a>)(?<!\/>)/';
                // 对锚链接在标签中和图片 alt 属性的判断
                $form_data[$site['article_content_field']] = preg_replace($patten,'<a href="'.$link['url'].'" target="_blank">' . $link['name'] . '</a>', $form_data[$site['article_content_field']],1);
            }
        }
        //是否插入图片
        if ($is_insert_img) {
            $img = MemberFile::order('update_time', 'asc')->where('img_class_id', $img_class_id)->find();
            if($img) {
                $form_data[$site['thumbnail_field']] =  str_replace("http://","https://",$img['filepath']);
                $form_data[$site['article_content_field']] = '<p style="text-align: center;"><img src="' .str_replace("http://","https://",$img['filepath']) . '"></p>' . $form_data[$site['article_content_field']];
                $img->force()->save();
            }
        }

        if ($site['other_fields']) {
            $other_fields = explode("\n", $site['other_fields']);
            foreach ($other_fields as $field) {
                $field = trim($field, "\r");
                if (strstr($field, ':')) {
                    [$key, $val] = explode(':', $field);
                    //替换相关标签
                    $val=repPushOtherLib($val);
                    $form_data[$key] = $val;
                }
            }
        }

        $cookies = [];
        if ($site['cookies']) {
            $other_fields = explode("\r\n", $site['cookies']);
            foreach ($other_fields as $field) {
                if (strstr($field, ':')) {
                    [$key, $val] = explode(':', $field);
                    $cookies[$key] = $val;
                }
            }
        }


        $headers = [];
        if ($site['headers']) {
            $other_fields = explode("\r\n", $site['headers']);
            foreach ($other_fields as $field) {
                if (strstr($field, ':')) {
                    [$key, $val] = explode(':', $field);
                    $headers[$key] = $val;
                }
            }
        }

        return [
            'id' => $plan_id,
            'member_id' => $article['member_id'],
            'article_id' => $id,
            'form' => $form_data,
            'cookies' => $cookies,
            'headers' => $headers,
            'url' => $url,
            'flag' => $site['publish_success_flag'],
            'site_id' => $site_id,
            'site_catid' => $site_class_id,
        ];
    }


    /**
     * @Apidoc\Title("站点今日推送量->昨日，今日清零")
     * todayToYesterday
     */
    public function todayToYesterday()
    {
        \app\common\model\Site::where('id','>', 0)->update([

            'yesterday_quantity' => Db::raw('today_quantity'),
            'today_quantity' => 0,
        ]);
        return 'success';
    }


    //将内容创建为正式的html,便于发布
    public function createHtml($text,$title=""){
        $title=trim($title);
        $text=trim($text);
        $text=trim($text,"\"");
        $text=trim($text);
        if($title){
            $title = preg_quote($title, '/');
            $text=preg_replace('/^'.$title.'$/m', "", $text);
            $text=preg_replace('/^标题：'.$title.'$/m', "", $text);
            $text=preg_replace('/^文章标题：'.$title.'$/m', "", $text);
            $text=preg_replace('/^title:'.$title.'$/m', "", $text);
            $text=preg_replace('/^《'.$title.'》/', '', $text);
            $text=preg_replace('/^<'.$title.'>/', '', $text);
        }
        $text=preg_replace('/^[\?\？]/u', '', $text);
        //过滤掉每一行开头为：首先，其次，然后等这样的字符
        $repWord="首先,其次,然后,第三,第四,第五,第六,第七,第八,第九,第十,然而,再次,综上所述,总结一下，最后一下,总结,然而,同时,一方面,另一方面,因此,与此同时,总而言之,另外,总之,非常后,最后,此外";
        foreach(explode(",",$repWord) as $str){
            $text = preg_replace('/^'.$str.'[，,、.。：:\p{P}]*[\r\n]*/mu', '', $text);
        }
        //
        $lines = preg_split('/\r\n|\r|\n/', $text); // 将文本按行分割成数组
        $pattern = "/^(.*)$/m"; // 匹配每一行文本
        $replacement = "<p>$1</p>"; // 替换为带有<p>标签的文本
        $lines_with_tags = array_map(function($line) use ($pattern, $replacement) {
            if($line)return preg_replace($pattern, $replacement, $line); // 对每一行都增加<p>标签
        }, $lines);
        $text_with_tags = implode("\n", $lines_with_tags); // 将所有行拼接成一个字符串
        file_put_contents("article/".$title.".txt",$text_with_tags);
        //替换单独一行的标题
        if($title){
            $text_with_tags=str_replace('<p>标题：'.$title.'</p>',"",$text_with_tags);
            $text_with_tags=str_replace('<p>'.$title.'</p>',"",$text_with_tags);
            $text_with_tags=str_replace('<p>文章标题：'.$title.'</p>',"",$text_with_tags);
            $text_with_tags=str_replace('<p>title:'.$title.'</p>',"",$text_with_tags);
            $text_with_tags=str_replace('<p>《'.$title.'》</p>',"",$text_with_tags);
            $text_with_tags=str_replace('<p><：'.$title.'></p>',"",$text_with_tags);
        }
        return $text_with_tags;
    }
    //执行批量标题任务
    public function doArticleTitleTask(){
        //针对异常的任务解锁（判断有没有任务未执行完成，并且最后执行时间在5分钟以前的（防止任务加锁后程序异常照成无法自动解锁））
        $deviant_task = \app\common\model\ArticleTitleTask::where([
            ["state","=",2],
            //["update_time","<",time()-300]
        ])->select();
        foreach($deviant_task as $v){
            \app\common\model\ArticleTitleTask::update([
                "id"=>$v['id'],
                "state"=>0,
            ]);
        }
        //
        $task = \app\common\model\ArticleTitleTask::where("state","=",0)->order("update_time asc")->find();
        if($task){
            //先将任务锁住（state变为2），防止当前任务没有完成下一个自动执行任务又来做这条，这样会照成生成的条数大于要生成的条数
            \app\common\model\ArticleTitleTask::update([
                "id"=>$task['id'],
                "state"=>2,
            ]);
            //剩余要生成的条数
            $generated_quantity=$task['num']-$task['has_num'];
            $generated_quantity=$generated_quantity>20?20:$generated_quantity;//这里经过多次实验，一次标题生成最好不要超过20个，
            if($generated_quantity<=0){die("没有需要执行的任务");}
            //
            $client = new Client([
                'base_uri' => 'https://open.bigmodel.cn/api/paas/v3/model-api/chatglm_std/invoke',
                'timeout' => 200,
                'verify' => false,
            ]);
//            $tokenModel = GptToken::order('update_time', 'asc')->where('id', '>', 0)->find();
//            $token = $tokenModel['token'];
//            $tokenModel->force()->save();
            //
            $msg = "生成{$generated_quantity}个关于'{$task['keywords']}'的文章标题,结果列表以如下格式返回,每行一个。格式```1 文章标题```";
            if($task['lang']){
                $msg.=" 生成语言为```{$task['lang']}```";
            }
            $tokenModel = GptToken::order('update_time', 'asc')->find();
            //
            $res = $client->post('', [
                'headers' => [
                    'Authorization' => ChatGpt::generate_token($tokenModel->token,80),
                    'Content-Type' => 'application/json',
                ],
                'json' => [
                    'prompt' => [
                        "role" => "user",
                        "content" => $msg
                    ],
                ],
            ]);
            $data = json_decode($res->getBody(), true);
            $content = $data['data']['choices'][0]['content'];
            $content=str_replace("\"","",$content);

            $content=explode("\\n",$content);

            if($content){
                //
                foreach ($content as $index => $article) {
                    $article=explode(' ', $article, 2)[1];
                    $article=trim($article);
                    if(!$article){
                        continue;
                    }
                    $article = preg_replace('/^\d+\.\s/', '', $article);
                    //字数少于6个字不入库
                    if(mb_strlen($article,'UTF-8')<6){
                        continue;
                    }
                    //2023.7.6新增加开始【判断任务数量是否已达到，如果已达到则终止】
                    $has_num=\app\common\model\Article::where("article_title_task_id","=",$task['id'])->count();
                    if($has_num>=$task['num']){
                        \app\common\model\ArticleTitleTask::update([
                            "id"=>$task['id'],
                            "has_num"=>$has_num,
                            "state"=>1,
                        ]);
                        echo $task['id']."-执行完成";exit;
                    }
                    //2023.7.6新增加结束

                    //查询标题是否已存在 如果文章标题重复 直接删除掉 不会入库
                    $exist = \app\common\model\Article::where([
                        'name' => $article,
                        'member_id' => $task['member_id'],
                    ])->find();
                    //如果标题不存在就入库
                    if(!$exist){
                        $article = \app\common\model\Article::create([
                            'name' => $article,
                            'state' => 0,
                            'lang' => $task['lang'],
                            'type' => $task['check_type'],
                            'member_id' => $task['member_id'],
                            'forbiddenwords_id' => $task['forbiddenwords_id'],
                            'article_class_id' => $task['article_class_id'],
                            'article_title_task_id' => $task['id'],
                            'length' => $task['length'],
                        ]);
                        ArticleContent::create([
                            'article_id' => $article->id,
                            'name' => ''
                        ]);
                    }
                }
                //更新数量
                $has_num=\app\common\model\Article::where("article_title_task_id","=",$task['id'])->count();
                $updateData=[];
                $updateData['id']=$task['id'];
                $updateData['has_num']=$has_num;
                if($has_num>=$task['num']){
                    $updateData['state']=1;
                }else{
                    $updateData['state']=0;
                }
                \app\common\model\ArticleTitleTask::update($updateData);
                echo "执行成功";exit;
            }
        }
        echo "没有要执行的任务";
    }



    //根据字符串提取文章内容和keywords
    private function extractKeywords($inputString) {
        // 将字符串按行拆分成数组
        $lines = explode("\n", $inputString);

        // 获取最后一行的内容
        $lastLine = array_pop($lines);

        // 将最后一行按 ":" 或 "：" 分割成数组
        $keywordsArray = preg_split('/[:：]/u', $lastLine, -1, PREG_SPLIT_NO_EMPTY);

        // 提取关键词字段
        $keywords = $keywordsArray[1];
        $keywords = str_replace(['。', '.'], '', $keywords);
        $keywords = str_replace(['，', '、'], ',', $keywords);
        //对关键词过滤，要求每个关键词必须是2个中文以上，最多不能超过[5,8]个关键词
        $newkeywords=[];
        foreach(explode(",",$keywords) as $key=>$val){
            if(mb_strlen($val,'UTF-8')>2){
                $newkeywords[]=$val;
            }
            if(count($newkeywords)>rand(5,8)){
                break;
            }
        }
        $keywords=implode(",",$newkeywords);
        $keywords=str_replace("\"","",$keywords);
        // 将数组重新组合成字符串
        $resultString = implode("\n", $lines);
        return array($resultString, $keywords);
    }

}
